package ru.compscicenter.databases.zaikina.common;

import ru.compscicenter.databases.zaikina.common.model.Document;
import ru.compscicenter.databases.zaikina.common.model.DocumentWithBody;
import ru.compscicenter.databases.zaikina.common.model.WordWithReferences;
import ru.compscicenter.databases.zaikina.nodes.NodeMain;

import java.util.ArrayList;
import java.util.HashMap;

public class FilesStorage implements Cloneable {
    private final Integer nodeId;
    private HashMap<String, Integer> paths = new HashMap<String, Integer>();
    private HashMap<Integer, DocumentWithBody> documents = new HashMap<Integer, DocumentWithBody>();
    private Integer maxFileId = 0;

    private IOProcessor<DocumentWithBody> io = new IOProcessor<DocumentWithBody>() {
        @Override
        protected DocumentWithBody parseItem(String str) {
            return DocumentWithBody.parse(str);
        }
    };
    private final PathGenerator pathGenerator;// = new PathGenerator(NodeMain.node.getNodeId());

    public FilesStorage(Integer nodeId) {
        this.nodeId = nodeId;
        pathGenerator = new PathGenerator(nodeId);
    }

    public void load() {
        int version = io.readVersion(pathGenerator.versionPath());
        if (version == 0) {
            return;
        }

        documents = io.loadObjectsFromDump(pathGenerator.fullObjectsPath(version));
        System.out.println("version = " + version + "; items.size = " + documents.size());
        for (DocumentWithBody item : documents.values()) {
            if (item == null) {
                continue;
            }

            //documents.put(item.getDocument().getId(), item);
            if (!paths.containsKey(item.getDocument().getTitle())) {
                paths.put(item.getDocument().getTitle(), item.getDocument().getId());
            }
        }
    }

    public ArrayList<WordWithReferences> add(ArrayList<String> newPaths) {
        ArrayList<WordWithReferences> words = new ArrayList<WordWithReferences>();

        for (String path : newPaths) {
            TextFile file = new TextFile(maxFileId, path);
            DocumentWithBody newDocument = new DocumentWithBody(new Document(maxFileId, path), file.getText());
            words.addAll(file.parse());
            paths.put(path, maxFileId);
            documents.put(newDocument.getDocument().getId(), newDocument);
        }

        ++maxFileId;
        return words;
    }

    public ArrayList<DocumentWithBody> get(ArrayList<Integer> ids) {
        ArrayList<DocumentWithBody> docs = new ArrayList<DocumentWithBody>();
        for (Integer id : ids) {
            docs.add(documents.get(id));
        }
        return docs;
    }

    public FilesStorage clone() {
        FilesStorage clone = new FilesStorage(nodeId);
        clone.paths = new HashMap<String, Integer>();
        for (String key : paths.keySet()) {
            clone.paths.put(new String(key), new Integer(paths.get(key).intValue()));
        }
        clone.documents = new HashMap<Integer, DocumentWithBody>();
        for (Integer key : documents.keySet()) {
            clone.documents.put(new Integer(key.intValue()), documents.get(key).clone());
        }
        clone.maxFileId = new Integer(maxFileId.intValue());
        return clone;
    }

    public void commit() {
        int version = io.readVersion(pathGenerator.versionPath()) + 1;
        io.writeObjectsToDump(pathGenerator.fullObjectsPath(version), documents);
        io.writeVersion(pathGenerator.versionPath(), version);
    }
}
